﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using Order.Common.Logger;
using Z.EntityFramework.Extensions;
using DbCommandInterceptor = Microsoft.EntityFrameworkCore.Diagnostics.DbCommandInterceptor;

namespace OrderWebApi
{
    public class HintCommandInterceptor : DbCommandInterceptor
    {
        private readonly Stopwatch _stopwatch;
        private readonly ILoggerHelper _loggerHelper;
        public HintCommandInterceptor(IServiceCollection services)
        {
            _stopwatch = new Stopwatch();
            _loggerHelper = services.BuildServiceProvider().GetService<ILoggerHelper>();
        }

        public override InterceptionResult<DbCommand> CommandCreating(CommandCorrelatedEventData eventData, InterceptionResult<DbCommand> result)
        {
            return base.CommandCreating(eventData, result);
        }

        public override DbCommand CommandCreated(CommandEndEventData eventData, DbCommand result)
        {
            return base.CommandCreated(eventData, result);
        }

        public override Task<InterceptionResult<DbDataReader>> ReaderExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result,
            CancellationToken cancellationToken = new CancellationToken())
        {
            _stopwatch.Start();
            return base.ReaderExecutingAsync(command, eventData, result, cancellationToken);
        }

        public override Task<DbDataReader> ReaderExecutedAsync(DbCommand command, CommandExecutedEventData eventData, DbDataReader result,
            CancellationToken cancellationToken = new CancellationToken())
        {
            return base.ReaderExecutedAsync(command, eventData, result, cancellationToken);
        }

        public override InterceptionResult DataReaderDisposing(DbCommand command, DataReaderDisposingEventData eventData,
            InterceptionResult result)
        {
            _stopwatch.Stop();
            var elapsedMilliseconds = _stopwatch.ElapsedMilliseconds;
            if (command.CommandText.Contains(ExecuteSqlType.SELECT.ToString()))
            {
                if (elapsedMilliseconds > 2000)
                {
                    _loggerHelper.LogInfo($"查询监控", $"\r\n执行时间:{elapsedMilliseconds} 毫秒,执行SQL:{command.CommandText}");
                }
            }
            return base.DataReaderDisposing(command, eventData, result);
        }
    }

    public enum ExecuteSqlType
    {
        INSTER,
        DELETE,
        UPDATE,
        SELECT
    }
}
